﻿using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public class ParseComponents : MonoBehaviour
{
    Dictionary<string, List<string>> nguics = new Dictionary<string, List<string>>();
    Dictionary<string, GameObject> prbPath = new Dictionary<string, GameObject>();
    public GameObject root;
    string path ="";
    // Use this for initialization
    void Start()
    {
        path = Application.dataPath + "/binaryFile.txt";
        //GetAllComponents<BoxCollider>(this.gameObject);//获得指定组件
        //GetAllComponents(root.transform,ref nguics);//获得预制的所有组件

        //反序列化
        nguics = DeSerialize<Dictionary<string, List<string>>>(path);
        //foreach (var pair in nguics)
        //{
        //    Debug.Log("<color=red>" + pair.Key + "</color>");
        //    for (int i = 0; i < pair.Value.Count; i++)
        //    {
        //        Debug.Log(pair.Value[i]);
        //    }
        //}
        //BindingAllScripts(this.transform);
        Recursive(root);

        foreach (var pair in prbPath)
        {
            Debug.Log(pair.Key);
            if (nguics.ContainsKey(pair.Key))
            {
                GameObject go = pair.Value;
                foreach (var script in nguics[pair.Key])
                {
                    Debug.Log(string.Format("<color=yellow>开始绑定{0}</color>", script));
                    go.AddComponent(System.Type.GetType(script));
                }
                Debug.Log("*************************************");
            }
            else
                continue;
        }
    }

    /// <summary>
    /// 获取指定的组件
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="go"></param>
    /// <returns></returns>
    public T GetAllComponents<T>(GameObject go)
    {
        T[] t = go.GetComponents<T>();
        if (t != null && t.Length > 0)
        {
            for (int i = 0; i < t.Length; i++)
            {
                Debug.Log(t[i]);
                if (t[i] is Component && (t[i] as Component).gameObject != null)
                {
                    return t[i];
                }
            }
        }
        return default(T);
    }

    /// <summary>
    /// 递归获取全部组件
    /// </summary>
    /// <param name="trans"></param>
    public void GetAllComponents(Transform trans, ref Dictionary<string, List<string>> nguiDic)
    {
        Component[] comps = trans.GetComponents(typeof(Component));
        foreach (var comp in comps)
        {
            if (null == comp)
            {
                Debug.LogError(comp + "is null");
                continue;
            }
            string child = NGUITools.GetHierarchy(comp.gameObject);
            //Debug.Log("origin:"+child);
            int idx = child.IndexOf('\\');
            if (idx != -1)
            {
                child = child.Substring(idx+1);
            }
            child = child.Replace('\\','/');
            //Debug.Log("after:"+child);


            string typeName = comp.GetType().ToString();
            //Debug.Log(typeName);
            if (typeName.StartsWith("UnityEngine"))//unity transform boxcolider...
            {
                //Object.DestroyImmediate(comp, true);
                Debug.Log(comp.name);
            }
            else//获得cs脚本
            {
                if (!nguics.ContainsKey(child))
                {
                    nguics.Add(child, new List<string>());
                }
                nguics[child].Add(typeName);
                DestroyImmediate(comp, true);
            }
        }
        for (int i = 0; i < trans.transform.childCount; i++)
        {
            Transform tran = trans.GetChild(i);
            if (tran.childCount >= 0)
            {
                //Debug.Log(string.Format("<color=yellow>-----------------递归获取{0}的组件-------------------</color>",tran.gameObject.name));
                GetAllComponents(tran, ref nguiDic);
            }
        }
        GetScriptsList();
    }

    public void BindingAllScripts(Transform root)
    {
        for (int i = 0; i < root.transform.childCount; i++)
        {
            Transform tran = root.GetChild(i);
            path = NGUITools.GetHierarchy(tran.gameObject);
            int idx = path.IndexOf('\\');
            if (idx != -1)
            {
                path = path.Substring(idx + 1);
            }
            path = path.Replace('\\', '/');
            if (tran.childCount >= 0)
            {
                Debug.Log(path);
                BindingAllScripts(tran);
            }
        }
    }

    void BindScripts(Transform root)
    {
        #region MyRegion
        //string prbKey = NGUITools.GetHierarchy(tran.gameObject);
        //int idx = prbKey.IndexOf('\\');
        //if (idx != -1)
        //{
        //    prbKey = prbKey.Substring(idx + 1);
        //}
        //prbKey = prbKey.Replace('\\', '/');
        //if (nguics.ContainsKey(prbKey))
        //{
        //    foreach (var script in nguics[prbKey])
        //    {
        //        Debug.Log(string.Format("<color=yellow>开始绑定{0}</color>", script));
        //        tran.gameObject.AddComponent(System.Type.GetType(script));
        //    }
        //} 
        #endregion
    }
    private void Recursive(GameObject parentGameObject)
    {
        //Do something you want
        string prbKey = NGUITools.GetHierarchy(parentGameObject.gameObject);
        int idx = prbKey.IndexOf('\\');
        if (idx != -1)
        {
            prbKey = prbKey.Substring(idx + 1);
        }
        prbKey = prbKey.Replace('\\', '/');
        if (!prbPath.ContainsKey(prbKey))
        {
            prbPath.Add(prbKey, parentGameObject);
        }
        else
        {
            Debug.Log(prbKey +" is already exists!");
        }
        foreach (Transform child in parentGameObject.transform)
        {
            if (parentGameObject.transform.childCount > 0)
                Recursive(child.gameObject);
            else
                return;
        }
    }

    /// <summary>
    /// 物体脚本关联
    /// </summary>
    void GetScriptsList()
    {
        Debug.Log("-------------------------------------------------");
        foreach (var pair in nguics)
        {
            Debug.Log("<color=red>"+pair.Key+"</color>");
            for (int i = 0; i < pair.Value.Count; i++)
            {
                Debug.Log(pair.Value[i]);
            }
        }
       
        Serialize(nguics, path);
    }


    /// <summary>
    /// 序列化信息
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    /// <param name="path"></param>
    public void Serialize<T>(T t, string path)
    {
        Debug.Log(path);
        if (File.Exists(path))
        {
            File.Delete(path);
        }
        try
        {
            BinaryFormatter formatter = new BinaryFormatter();
            Stream stream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
            formatter.Serialize(stream, t);
            stream.Flush();
            stream.Close();
        }
        catch (System.Exception e)
        {
            Debug.Log(e.Message);
        }
    }

    /// <summary>
    /// 反序列化
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="path"></param>
    /// <returns></returns>
    public T DeSerialize<T>(string path)
    {
        if (!File.Exists(path))
            return default(T);
        try
        {
            BinaryFormatter formatter = new BinaryFormatter();
            Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
            T t = (T)formatter.Deserialize(stream);
            stream.Flush();
            stream.Close();
            return t;
        }
        catch (System.Exception e)
        {
            Debug.Log(e.Message);
        }
        return default(T);
    }
}
